home *** CD-ROM | disk | FTP | other *** search
/ TeX 1995 July / TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO / graphics / gnuplot / contrib / campbell / bars.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-04-27  |  6.4 KB  |  248 lines

  1. #include <stdio.h>
  2. #include <math.h>
  3. #include "gtplot.h"
  4.  
  5. main(argc, argv)
  6. int argc;
  7. char *argv[];
  8. {
  9.    FILE *in, *fopen();
  10.    struct termentry *t;
  11.  
  12.    if (argc > 2) 
  13.       usage();
  14.  
  15.    if (argc == 0)
  16.       in = stdin;
  17.    else if ((in = fopen (argv[1], "r")) == NULL) {
  18.       fprintf (stderr, "Can't open %s\n", argv[1]);
  19.       exit();
  20.    }
  21.  
  22.    GToutfile = stdout;
  23. /* 
  24.    still missing the signal handler--especially to make sure we
  25.    always reset the terminal before we leave on the signals that
  26.    gnuplot normally traps (2 of them).
  27. */
  28.    gt_init_terminal();  /* Hope we set term here--if not need too later. */
  29.    if (!GTterm) {
  30.       fprintf (stderr, "Sorry, unknown terminal type\n");
  31.       exit(1);
  32.    }
  33.    t = >term_tbl[GTterm];
  34. #ifdef WAIT
  35.   gt_test_term(); 
  36. #endif
  37.    bar_graph(in);
  38.    getchar();
  39.    (*t->reset)();
  40. }
  41.  
  42. bar_graph(in)
  43. FILE *in;
  44. /* 
  45.    Routine to make a bar graph out of a list of points.  The list of
  46.    points come from the file named on the command line.
  47.  
  48.    Parameter:
  49.  
  50.           in:  Pointer to file descriptor containing list of points.
  51. */
  52. {
  53. #define MAXBUF 255
  54.    struct termentry *t = >term_tbl[GTterm];
  55.    int *pnum, bar_w, x_loc, height, lcnt, max_points=t->xmax/2;
  56.    int err, i, k, result, bar_cnt=0;
  57.    float *pval, scale, pmax, pmin, dummy;
  58.    char buf[MAXBUF], *malloc();
  59.  
  60. /* Read everything into an array of floats with room for 10 per line. */
  61.    pval = (float *)malloc (10*sizeof(float)*max_points);
  62.    pnum = (int *)malloc (sizeof(int )*max_points);
  63.    pmin = VERYLARGE;
  64.    pmax = -VERYLARGE;
  65.    err = 0;
  66.    for (lcnt=0; fgets (buf, MAXBUF, in) != NULL; ++lcnt) {
  67.       result = sscanf(buf,"%f %f %f %f %f %f %f %f %f %f %f", 
  68.         &pval[lcnt*10], &pval[lcnt*10+1], &pval[lcnt*10+2], &pval[lcnt*10+3], 
  69.         &pval[lcnt*10+4], &pval[lcnt*10+5], &pval[lcnt*10+6], &pval[lcnt*10+7], 
  70.         &pval[lcnt*10+8], &pval[lcnt*10+9], &dummy);
  71.       if (result > 10) {
  72.          err = 1;
  73.          break;
  74.       }
  75.    /* Find the max and min of the overall array. */
  76.       for (k = 0; k < result; ++k) {
  77.          if (pval[lcnt*10+k] > pmax) pmax = pval[lcnt*10+k];
  78.          if (pval[lcnt*10+k] < pmin) pmin = pval[lcnt*10+k];
  79.       }
  80.       pnum[lcnt] = result;  /* number of items on this line. */
  81.       bar_cnt += result;
  82.       if (bar_cnt > max_points) {
  83.          err = 1;
  84.          break;
  85.       }
  86.    }
  87.    if (bar_cnt >= max_points) {
  88.       fprintf (stderr, "Error on input: more than %d data elements\n", bar_cnt);
  89.       exit(1);
  90.    }
  91.    if (err) {
  92.       fprintf (stderr, "Error on input: line %d\n", lcnt);
  93.       exit(1);
  94.    }
  95.  
  96. /* Draw the bars represented by the array pval. */
  97.    bar_draw (pval, pnum, lcnt, pmax, pmin);
  98. }
  99.  
  100.  
  101. usage()
  102. {
  103.    fprintf (stderr, "usage: bar [file]\n");
  104.    exit(1);
  105. }
  106.  
  107.  
  108. #define SOLID
  109.  
  110. bar_draw (pval, pnum, lcnt, pmax, pmin)
  111. float pval[], pmax, pmin;
  112. int pnum[], lcnt;
  113. /*
  114.    Routine to draw the bars represented by values in array pval.
  115.  
  116.    Parameters:
  117.  
  118.          pval: array of groups of points to take as bar heights.
  119.  
  120.          pnum: array of the number of points in the ith bar group.
  121.  
  122.          lcnt: number of groups (10 at most per group) of bars to draw.
  123.  
  124.          pcnt: number of points to draw. 
  125.  
  126.          pmax: largest value in the pval array.
  127.  
  128.          pmin: smallest value in the pval array.
  129. */
  130. {
  131.    int i, j, k, bar_cnt, zero, y_loc, bar_h, bar_w, x_loc;
  132.    float scale, range, yoff=0.0;
  133.    struct termentry *t = >term_tbl[GTterm];
  134.  
  135. #define GAP (t->v_char/2)  /* Space between bar and top (or bott) of graph. */
  136.  
  137. /* Compute scaling factor zero point, etc for this bar graph. */
  138.    if (pmin < 0.0) {
  139.    /* Make a gap at the top and at the bottom of the bar graph */
  140.       range = pmax - pmin;
  141.       scale = (t->ymax - 2*GAP)/range;
  142.       zero = (0.0-pmin) * scale + GAP + 0.5;
  143.       yoff = pmin - GAP/scale; 
  144.    }
  145.    else {
  146.    /* Make a gap only at the top of the bar graph */
  147.       range = pmax;
  148.       scale = (t->ymax - GAP)/range;
  149.       zero = 0;
  150.    }
  151.  
  152. /* Compute the width of the bar graph. */
  153.    for (bar_cnt=i=0; i < lcnt; ++i)
  154.       bar_cnt += pnum[i]+1;
  155.  
  156.    bar_w = t->xmax/bar_cnt;
  157.  
  158. /* Compute start of first bar. */
  159.    x_loc = (t->xmax - (bar_cnt-1)*bar_w)/2.0 + 0.5;
  160.  
  161. #ifdef DEBUG
  162.    for (i=0; i < lcnt; ++i) {
  163.       fprintf (stderr, "%d: pval[%d] = ", pnum[i], i*10);
  164.       for (k=0; k < pnum[i]; ++k) {
  165.          fprintf (stderr, "%f ", pval[i*10+k]);
  166.       }
  167.       fprintf (stderr,"\n");
  168.    }
  169.    fprintf (stderr, "lcnt = %d\t", lcnt);
  170.    fprintf (stderr, "scale = %f\t", scale);
  171.    fprintf (stderr, "pmax = %f\t", pmax);
  172.    fprintf (stderr, "pmin = %f\n", pmin);
  173.    fprintf (stderr, "zero = %d\t", zero);
  174.    fprintf (stderr, "bar_cnt = %d\n", bar_cnt);
  175.    fprintf (stderr, "bar_w = %d\n", bar_w);
  176.    fprintf (stderr, "Hit return\n");
  177.    (void )getchar();
  178. #endif
  179.  
  180. /* Put device into graphics mode. */
  181.    if (!GTterm_init) {
  182.       (*t->init)();
  183.       GTterm_init = TRUE;
  184.    }
  185.    (*t->graphics)();  /* Default linetype is 0 (solid line) */
  186.  
  187. /* Draw a box around the plot. */
  188.       (*t->move)(0,0);
  189.       (*t->vector)(0,t->ymax-1);
  190.       (*t->vector)(t->xmax-1,t->ymax-1);
  191.       (*t->vector)(t->xmax-1, 0);
  192.       (*t->vector)(0,0);
  193.  
  194. /* Draw the zero line. */
  195.       if (zero != 0) {
  196.          (*t->move)(x_loc,zero);
  197.          (*t->vector)(t->xmax-x_loc-1,zero);
  198.       }
  199.  
  200. /* Draw lcnt bars of bar_h scale*pval[i] and width bar_w. */
  201.    for (i = 0; i < lcnt; ++i) {
  202.       for (k = 0; k < pnum[i]; ++k) {
  203.          bar_h = (int )((scale * (pval[i*10+k] - yoff)) + 0.5);
  204.  
  205. #ifdef DEBUG
  206.          fprintf (stderr, "bar_h = %d, linetype = %d\n", bar_h, k);
  207. #endif
  208.    
  209.          (*t->move)(x_loc,zero);
  210.          (*t->vector)(x_loc, bar_h);
  211.          (*t->vector)(x_loc+bar_w, bar_h);
  212.          (*t->vector)(x_loc+bar_w, zero);
  213. #ifdef SOLID
  214.          if (k % 6 < 4) {
  215.             for (j=0; j < bar_w; ++j) {
  216.             /* Terminal drivers define points as unsigned int... */
  217.                (*t->move)(x_loc+j,zero);
  218.                if (j % (k % 4 + 1) == 0)
  219.                   (*t->vector)(x_loc+j,bar_h);
  220.             }
  221.          }
  222.          else {
  223.             int lower, upper;
  224.             if (zero < bar_h) {
  225.                lower = zero;
  226.                upper = bar_h;
  227.             }
  228.             else {
  229.                lower = bar_h;
  230.                upper = zero;
  231.             }
  232.             for (j=lower; j < upper; ++j) {
  233.                if (j % (k % 3 + 1) == 0) {
  234.                   (*t->move)(x_loc,j);
  235.                   (*t->vector)(x_loc+bar_w,j);
  236.                }
  237.             }
  238.          }
  239. #endif
  240.          x_loc += bar_w;
  241.       }
  242.       x_loc += bar_w;
  243.    }
  244. /* Back into text mode (to see the plot generated) */
  245.    (*t->text)();
  246.  
  247. }
  248.